package com.authsphere.plugin.decrypt;

import com.authsphere.common.utils.CryptoUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.Objects;

/**
 * @program: AuthSphere
 * @description:
 * @author: YuKai Fan
 * @create: 2025/3/13 16:23
 **/
public class RsaRequestBodyDecoder extends AbstractRequestBodyDecoder {
    private static final String AUTH_SPHERE_SECRET_KEY = "META-INF/authsphere/rsa_secret.key";
    private final String secretKey;
    public RsaRequestBodyDecoder(String secretKey) {
        this.secretKey = secretKey;
    }

    public RsaRequestBodyDecoder(ClassLoader classLoader) {
        URL url = Objects.nonNull(classLoader) ? classLoader.getResource(AUTH_SPHERE_SECRET_KEY)
                : ClassLoader.getSystemResource(AUTH_SPHERE_SECRET_KEY);
        if (Objects.nonNull(url)) {
            try (InputStream inputStream = url.openStream()) {
                this.secretKey = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
            } catch (IOException e) {
                throw new RuntimeException("Failed to read secret ket file.", e);
            }
        } else {
            throw new RuntimeException("Secret key file not found in resources.");
        }
    }

    public RsaRequestBodyDecoder() {
        this(RsaRequestBodyDecoder.class.getClassLoader());
    }

    @Override
    protected String doDecrypt(String encoder) {
        return decrypt(encoder, this.secretKey);
    }

    @Override
    public String decrypt(String encryptedData, String secretKey) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return CryptoUtils.decryptWithRSA(encryptedData, keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(this.secretKey))));
        } catch (Exception e) {
            // todo 解密异常
            throw new RuntimeException(e);
        }
    }
}
